(function ($, doc, undefined) {

    var now = new Date(),
        _toString = Object.prototype.toString;
        
    /**
     * 获取指定cookie的对象格式.
     */     
    $.getCookieObj = function (name) {
        var cookieVal = $.cookie(name);
        if(_toString.call(cookieVal) == '[object String]'){
            try{
                cookieVal = JSON.parse(cookieVal);
            }catch(e){}
        }
        return cookieVal;
    };
    
    //更新指定的cookie对象.
    $.updateCookieObj = function(name, updaterFun, options){        
        var newCookieObj = updaterFun($.getCookieObj(name));
        return newCookieObj ? $.cookie(name, newCookieObj, options) : false;
    };
    
    //-------------------------------------------------------------------------------------------------
    
    //更新指定的cookie.
    $.updateCookie = function(name, updaterFun, options){        
        var newCookie = updaterFun($.cookie(name));
        return newCookie ? $.cookie(name, newCookie, options) : false;
    };
    
    /**
     * 设置 cookie.
     * @param name {String|Array} Cookie名字|参数数组.
     * @param value {String|Object} Cookie值.
     * @param options {Object} Cookie设置选项. 
     * @return {String|Array} Cookie串|Cookie串数组.
     */
	$.cookie = function (name, value, options) {	    
	    //兼容 $.cookie([ ['account','stone'], ['name', 'Stone Liu'], ['pwd', '#@$@#$'] ]).
	    if($.isArray(name)){
	        var cookieArr = name, 
                resultArr = [];
	        for(var i=0, cookieCount=cookieArr.length; i<cookieCount; i++){
	            resultArr.push( $.cookie.apply(this, cookieArr[i]) );
	        }
	        return resultArr;
	    } 
	    //兼容 $.cookie({ account : 'stone', name : 'Stone Liu' });
	    else if($.isPlainObject(name)){
	        var cookieMap = name,
                resultArr = [];
	        Object.each(cookieMap, function(name, value){
	            resultArr.push( $.cookie(name, value) );
	        });
	        return resultArr;
	    }
	    options = $.extend({}, $.cookie.defaults, options);
		//写入cookie.
		if (!(_toString.call(value) == "[object Undefined]")) {
		    if($.isPlainObject(value) || $.isArray(value)){
		        value = JSON.stringify(value);
		    }
			if (value === null) {
				options.expires = new Date(0);
			}
			if ($.isNumeric(options.expires)) {
				var days = options.expires, 
				    t = options.expires = new Date();
				t.setDate(t.getDate() + days);
			}
			value = String(value);
			return (doc.cookie = [
				encodeURIComponent(name) + '=' + ( options['isRaw'] ? value : encodeURIComponent(value) ),
				options.expires ? ';expires=' + options.expires.toUTCString() : '', 
				options.path    ? ';path=' + options.path : '',
				options.domain  ? ';domain=' + options.domain : '',
				options.secure  ? ';secure' : ''
			].join(''));
		}
        //读取cookie.
        else {    	
    		var decode = options['isRaw'] ? Function.pipe : function(s){return decodeURIComponent(s.replace(/\+/g, ' '));};
    		var cookies = doc.cookie.split('; ');
    		for (var i = 0, parts; (parts = cookies[i] && cookies[i].split('=')); i++) {
    			if (decode(parts.shift()) === name) {
    				return decode(parts.join('='));
    			}
    		}
		}
		return null;
	};    
    /**
     * cookie 默认设置.
     */
    $.cookie.defaults = {
        isRaw : false,  //默认对cookie的值编码(encodeURIComponent).
        path : '/', 
        //expires : undefined //默认在session内有效.
        expires : new Date( now.setFullYear( now.getFullYear() + 1000 ) )  //默认永远有效
    }; 
    
    //-------------------------------------------------------------------------------------------------
      
    /**
     * 删除cookie.
     * @param {String} name
     * @param {Object} options
     * @return {Boolean} 是否删除成功.
     */
	$.removeCookie = function (name, options) {
		if ($.cookie(name) !== null) {
			$.cookie(name, null, options);
			return true;
		}
		return false;
	};
	/**
	 * 判断cookie是否已经启用.
	 */
	$.isCookieEnabled = function() {
	    if(_toString.call(navigator.cookieEnabled) == "[object Undefined]"){
            var name = "__testcookie_" + (+(new Date()));
            $.cookie(name, "testvalue");        
            navigator.cookieEnabled = !!($.cookie(name));    
	    }
        return navigator.cookieEnabled;
    };
})($, document);